package ar.com.photo_admin.service

import javax.annotation.PostConstruct

import org.codehaus.groovy.grails.commons.GrailsApplication
import org.grails.plugins.imagetools.*
import ar.com.photo_admin.domain.*
import grails.converters.*
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO

/**
 * Service for domain class EventPhoto
 */
class EventPhotoService extends BaseService {
	
	def THUMBNAIL_SIZE = 100
	def THUMBNAIL_MEDIUM_SIZE = 200	
	
	def shoppingCartServiceBean
	
	def tokenGeneratorService
	
	/**
	 * Gets an EventPhoto using an id if the logged in user is owner of the photo.
	 */
	def getAndCheckOwnership(id) {
		User user = springSecurityService.currentUser
		
		def photo = EventPhoto.get(id)

		user.isOwner(photo) ? photo : null
	}
	
	/**
	 * Gets the EventPhotos using ids if the logged in user is owner of the photo.
	 */
	def getAllAndCheckOwnership(ids) {
		User user = springSecurityService.currentUser
		
		EventPhoto.getAll(ids).findAll { user.isOwner(it) }
	}	
	
	/**
	 * Generates a thumbnail of the given event photo and stores it in the server.
	 */
	def generateThumbnail(EventPhoto eventPhoto, thumbnailSize) {
		def imageTool = new ImageTool()						
		
		imageTool.load(eventPhoto.pathInServer)		
		imageTool.square()
		imageTool.swapSource()
		imageTool.thumbnail(thumbnailSize)
		imageTool.writeResult(eventPhoto.thumbnailPathInServer, "JPEG")			
	}
	
	/**
	 * Generates a medium size thumbnail of the given event photo and stores it in the server.
	 */
	def generateMediumThumbnail(EventPhoto eventPhoto, thumbnailSize) {
		def imageTool = new ImageTool()
		
		imageTool.load(eventPhoto.pathInServer)
		imageTool.square()
		imageTool.swapSource()
		imageTool.thumbnail(thumbnailSize)
		imageTool.writeResult(eventPhoto.thumbnailMediumPathInServer, "JPEG")
	}
	
	/**
	 * Creates a temporal photo.
	 */
	def createPhotoTemporally(def eventNumber, byte[] fileBytes, def originalFilename) {

		def filename = originalFilename
		def filenameWithoutExtension = splitStringInNameAndExtension(filename)[0]
		def hashPrefix = generateHashPrefix(eventNumber, fileBytes, originalFilename)
		
		// Server URL.
		def eventUrl = getEventNotHostedPhotosUrl(eventNumber) + hashPrefix
		def serverUrl = eventUrl + filename
		def serverThumbnailUrl = eventUrl + filenameWithoutExtension + "_s.JPEG"
		def serverThumbnailMediumUrl = eventUrl + filenameWithoutExtension + "_m.JPEG"
		
		// Server path.
		def eventPath = getEventNotHostedPhotosPath(eventNumber) + hashPrefix
		def photoPath = eventPath + filename
		def thumbnailPath = eventPath+ filenameWithoutExtension + "_s.JPEG"
		def thumbnailMediumPath = eventPath+ filenameWithoutExtension + "_m.JPEG"
		
		def destinationFile = new File(photoPath)

		destinationFile.delete()
		destinationFile << fileBytes
		
		BufferedImage img = ImageIO.read(destinationFile)		
		
		def photo = new EventPhoto(url: serverUrl, 
								   pathInServer: photoPath,
								   thumbnailPathInServer: thumbnailPath, 
								   thumbnailMediumPathInServer: thumbnailMediumPath,
								   thumbnailUrl: serverThumbnailUrl, 
								   thumbnailMediumUrl: serverThumbnailMediumUrl,
								   name: filename, 
								   temporalEventNumber: eventNumber, 
								   hosted:false, 
								   height: img.getHeight(), 
								   width: img.getWidth(),
							   	   user: springSecurityService?.getCurrentUser())
		
		this.generateThumbnail(photo, THUMBNAIL_SIZE)
		this.generateMediumThumbnail(photo, THUMBNAIL_MEDIUM_SIZE)

		if (photo.hasErrors())
			log.error "Error in photo: " + photo.errors
	
		photo = photo.save(flush:true)
		
		return photo
	}
	
	/**
	 * Generates a hash to be used in the filename to prevent the hack of photo URL. 
	 */
	def generateHashPrefix(def eventNumber, byte[] fileBytes, def originalFilename) {
		tokenGeneratorService.generateTokenOfList([eventNumber, fileBytes, originalFilename])
	}

	/**
	 * Split the filename in name and extension.
	 */
	def splitStringInNameAndExtension(name) {
		def vars = name.split("\\.")
		
		def start = new StringBuilder()
		for (int i = 0; i < vars.size() - 1; i++){
			start.append(vars[i])
		}
		
		return [ start , vars[vars.size()-1] ]
	}
	
	/**
	 * Gets photos in JSON format.
	 */
	def convertPhotosToJSON(photos) {
		shoppingCartServiceBean = applicationContext.getBean("shoppingCartService")
			
		Collection results = []
		
		def result
		for (EventPhoto photo : photos) {
			
			result = [:]			
			result['photoId'] = photo.id
			result['name'] = photo.name						
			result['url'] = photo.hosted ? photo.urlInHost : photo.url
			result['thumbnailUrl'] = photo.hosted ? photo.thumbnailUrlInHost : photo.thumbnailUrl
			result['thumbnailMediumUrl'] = photo.hosted ? photo.thumbnailMediumUrlInHost : photo.thumbnailMediumUrl
			result['inCart'] = shoppingCartServiceBean.isPhotoInLoggedUserCart(photo)
			
			results << result
		}
		
		return results as JSON
	}	
}